/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package game.gamemath;

import java.lang.Math;
/**
 *
 * @author UtMan
 */
public class vec2
{
    float[] xy = new float[2];

    public vec2()
    {
        xy[0] = 0;
        xy[1] = 0;
    }

    public vec2(float x, float y)
    {
        xy[0] = x;
        xy[1] = y;
    }

    public float X()
    {
        return xy[0];
    }

    public void X(float x)
    {
        xy[0] = x;
    }

    public float Y()
    {
        return xy[1];
    }

    public void Y(float y)
    {
        xy[1] = y;
    }

    public float[] XY()
    {
        return xy;
    }

    public void XY(float[] xy)
    {
        if(xy.length < 2 || xy.length > 2)
        {
            //TODO error check
            return;
        }
        this.xy = xy;
    }

    public vec2 Plus(vec2 rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() + rhs.X());
        ret.Y(this.Y() + rhs.Y());
        return ret;
    }

    public vec2 Plus(vec3 rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() + rhs.X());
        ret.Y(this.Y() + rhs.Y());
        return ret;
    }

    public vec2 Plus(vec4 rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() + rhs.X());
        ret.Y(this.Y() + rhs.Y());
        return ret;
    }

    public vec2 Plus(float rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() + rhs);
        ret.Y(this.Y() + rhs);
        return ret;
    }

    public vec2 Minus(vec2 rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() - rhs.X());
        ret.Y(this.Y() - rhs.Y());
        return ret;
    }

    public vec2 Minus(vec3 rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() - rhs.X());
        ret.Y(this.Y() - rhs.Y());
        return ret;
    }

    public vec2 Minus(vec4 rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() - rhs.X());
        ret.Y(this.Y() - rhs.Y());
        return ret;
    }

    public vec2 Minus(float rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() - rhs);
        ret.Y(this.Y() - rhs);
        return ret;
    }

    public vec2 MulitpliedBy(vec2 rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() * rhs.X());
        ret.Y(this.Y() * rhs.Y());
        return ret;
    }

    public vec2 MulitpliedBy(vec3 rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() * rhs.X());
        ret.Y(this.Y() * rhs.Y());
        return ret;
    }

    public vec2 MulitpliedBy(vec4 rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() * rhs.X());
        ret.Y(this.Y() * rhs.Y());
        return ret;
    }

    public vec2 MulitpliedBy(float rhs)
    {
        vec2 ret = new vec2();
        ret.X(this.X() * rhs);
        ret.Y(this.Y() * rhs);
        return ret;
    }

    public vec2 DividedBy(vec2 rhs)
            throws DivideByZeroException
    {
        if(rhs.X() == 0 || rhs.Y() == 0)
            throw new DivideByZeroException();
        vec2 ret = new vec2();
        ret.X(this.X() / rhs.X());
        ret.Y(this.Y() / rhs.Y());
        return ret;
    }

    public vec2 DividedBy(vec3 rhs)
            throws DivideByZeroException
    {
        if(rhs.X() == 0 || rhs.Y() == 0)
            throw new DivideByZeroException();
        vec2 ret = new vec2();
        ret.X(this.X() / rhs.X());
        ret.Y(this.Y() / rhs.Y());
        return ret;
    }

    public vec2 DividedBy(vec4 rhs)
            throws DivideByZeroException
    {
        if(rhs.X() == 0 || rhs.Y() == 0)
            throw new DivideByZeroException();
        vec2 ret = new vec2();
        ret.X(this.X() / rhs.X());
        ret.Y(this.Y() / rhs.Y());
        return ret;
    }

    public vec2 DividedBy(float rhs)
            throws DivideByZeroException
    {
        if(rhs == 0)
            throw new DivideByZeroException();
        vec2 ret = new vec2();
        ret.X(this.X() / rhs);
        ret.Y(this.Y() / rhs);
        return ret;
    }

    public vec2 ModBy(vec2 rhs)
            throws DivideByZeroException
    {
        if(rhs.X() == 0 || rhs.Y() == 0)
            throw new DivideByZeroException();
        vec2 ret = new vec2();
        ret.X(this.X() % rhs.X());
        ret.Y(this.Y() % rhs.Y());
        return ret;
    }

    public vec2 ModBy(vec3 rhs)
            throws DivideByZeroException
    {
        if(rhs.X() == 0 || rhs.Y() == 0)
            throw new DivideByZeroException();
        vec2 ret = new vec2();
        ret.X(this.X() % rhs.X());
        ret.Y(this.Y() % rhs.Y());
        return ret;
    }

    public vec2 ModBy(vec4 rhs)
            throws DivideByZeroException
    {
        if(rhs.X() == 0 || rhs.Y() == 0)
            throw new DivideByZeroException();
        vec2 ret = new vec2();
        ret.X(this.X() % rhs.X());
        ret.Y(this.Y() % rhs.Y());
        return ret;
    }

    public vec2 ModBy(float rhs)
            throws DivideByZeroException
    {
        if(rhs == 0)
            throw new DivideByZeroException();
        vec2 ret = new vec2();
        ret.X(this.X() % rhs);
        ret.Y(this.Y() % rhs);
        return ret;
    }

    public boolean Equals(vec2 rhs)
    {
        if(this.xy == rhs.xy)
            return true;
        return false;
    }

    public void PlusEquals(vec2 rhs)
    {
        this.xy[0] += rhs.xy[0];
        this.xy[1] += rhs.xy[1];
    }

    public void PlusEquals(float rhs)
    {
        this.xy[0] += rhs;
        this.xy[1] += rhs;
    }

    public void MinusEquals(vec2 rhs)
    {
        this.xy[0] -= rhs.xy[0];
        this.xy[1] -= rhs.xy[1];
    }

    public void MinusEquals(float rhs)
    {
        this.xy[0] -= rhs;
        this.xy[1] -= rhs;
    }

    public void MultiplyEquals(vec2 rhs)
    {
        this.xy[0] *= rhs.xy[0];
        this.xy[1] *= rhs.xy[1];
    }

    public void MultiplyEquals(float rhs)
    {
        this.xy[0] *= rhs;
        this.xy[1] *= rhs;
    }

    public void DivideEquals(vec2 rhs)
            throws DivideByZeroException
    {
        if(rhs.X() == 0 || rhs.Y() == 0)
            throw new DivideByZeroException();
        this.xy[0] /= rhs.xy[0];
        this.xy[1] /= rhs.xy[1];
    }

    public void DivideEquals(float rhs)
            throws DivideByZeroException
    {
        if(rhs == 0)
            throw new DivideByZeroException();
        this.xy[0] /= rhs;
        this.xy[1] /= rhs;
    }
    
    public float Magnitude()
    {
        float mag = 0.0f;
        mag = (float)java.lang.Math.sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
        return mag;
    }

    public vec2 Normalize()
    {
        float rsqrt = 1 / Magnitude();
        xy[0] *= rsqrt;
        xy[1] *= rsqrt;
        return this;
    }

    public vec2 Negate()
    {
        xy[0] = -xy[0];
        xy[1] = -xy[1];
        return this;
    }

    public static vec2 Zero()
    {
        return new vec2(0, 0);
    }

    public static vec2 Right()
    {
        return new vec2(1, 0);
    }

    public vec2 Up()
    {
        return new vec2(0, 1);
    }

    public static vec2 One()
    {
        return new vec2(1, 1);
    }
}
